/**
 * @author ming
 * @date 2021/2/14 17:33
 * @desc 日志类
 */
package g

import (
	"encoding/json"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"strings"
)

// 控制台日志配置
type consoleLogConfig struct {
	Level    int  `json:"level"`
	Colorful bool `json:"color"`
}

// 文件日志配置
type fileLogConfig struct {
	Filename   string   `json:"filename"`
	MaxLines   int      `json:"maxlines"`
	MaxSize    int      `json:"maxsize"`
	Daily      bool     `json:"daily"`
	MaxDays    int64    `json:"maxdays"`
	Rotate     bool     `json:"rotate"`
	Level      int      `json:"level"`
	Perm       string   `json:"perm"`
	RotatePerm string   `json:"rotateperm"`
	Separate   []string `json:"separate"`
}

const (
	debugLevel     = "debugLevel"
	infoLevel      = "infoLevel"
	noticeLevel    = "noticeLevel"
	warnLevel      = "warn"
	errorLevel     = "error"
	criticalLevel  = "critical"
	alertLevel     = "alert"
	emergencyLevel = "emergency"

	consoleAdapter   = "console"
	fileAdapter      = "file"
	multiFileAdapter = "multiFile"
)

var (
	Log *logs.BeeLogger
)

func init() {
	logAdapter := beego.AppConfig.String("log-adapter")
	logLevel := beego.AppConfig.String("log-level")
	level := parseLogLevel(logLevel)

	if logAdapter == consoleAdapter {
		Log = newConsoleAdapter(level)
	} else if logAdapter == fileAdapter || logAdapter == multiFileAdapter {
		Log = newFileAdapter(logAdapter, level)
	} else {
		Log = logs.GetBeeLogger()
	}
}

func newConsoleAdapter(level int) *logs.BeeLogger {
	logColor := beego.AppConfig.DefaultBool("log-color", true)

	clc := consoleLogConfig{
		Level:    level,
		Colorful: logColor,
	}

	config, _ := json.Marshal(clc)
	logger := logs.NewLogger(100)
	logger.SetLogger(logs.AdapterConsole, string(config))

	return logger
}

func newFileAdapter(adapter string, level int) *logs.BeeLogger {
	logFile := beego.AppConfig.String("log-file")
	logMaxLines := beego.AppConfig.DefaultInt("log-max-lines", 0)
	logMaxSize := beego.AppConfig.DefaultInt("log-max-size", 1<<25)
	logDaily := beego.AppConfig.DefaultBool("log-daily", true)
	logMaxDays := beego.AppConfig.DefaultInt64("log-max-days", 7)
	logPerm := beego.AppConfig.String("log-perm")

	flc := fileLogConfig{
		Filename:   logFile,
		MaxLines:   logMaxLines,
		MaxSize:    logMaxSize,
		Daily:      logDaily,
		MaxDays:    logMaxDays,
		Perm:       logPerm,
		RotatePerm: logPerm,
		Level:      level,
	}

	if adapter == fileAdapter {
		config, _ := json.Marshal(flc)
		logger := logs.NewLogger(100)
		logger.SetLogger(logs.AdapterFile, string(config))

		return logger
	}

	if adapter == multiFileAdapter {
		logSeparate := beego.AppConfig.String("log-separate")
		separates := strings.Split(logSeparate, ",")
		flc.Separate = separates

		config, _ := json.Marshal(flc)
		logger := logs.NewLogger(100)
		logger.SetLogger(logs.AdapterMultiFile, string(config))

		return logger
	}

	return logs.GetBeeLogger()
}

func parseLogLevel(logLevel string) int {
	level := logs.LevelInfo

	switch logLevel {
	case debugLevel:
		level = logs.LevelDebug
		break
	case infoLevel:
		level = logs.LevelInfo
		break
	case noticeLevel:
		level = logs.LevelNotice
		break
	case warnLevel:
		level = logs.LevelWarning
		break
	case errorLevel:
		level = logs.LevelError
		break
	case criticalLevel:
		level = logs.LevelCritical
		break
	case alertLevel:
		level = logs.LevelAlert
		break
	case emergencyLevel:
		level = logs.LevelEmergency
		break
	default:
		break
	}

	return level
}
